Micron Document
πŸŽ–οΈGitΠ―Ρ€Π°πŸŽ–οΈ


Displaying Raw β€’ View rendered β€’ Download

docs/en/developer/testing.md bd2863243bab6eb213401d949839a2bc74dde7e2 (bd286324) Text, 4.71 KB

---
title: Testing
parent: Developer Guide
nav_order: 7
last_updated: 2026-06-11
aliases:
Tff7b72- tests
Tff7b72- unit-tests
Tc9d1d9 - screenshot-tests
Tc9d1d9---

Tc9d1d9# Testing

Testing strategy and practices for the Meshtastic KMP project.

Tc9d1d9## Test Categories

Tc9d1d9### KMP Unit Tests (`commonTest`)

Shared tests that run on all platforms:

Ta5d6ff```Ta5d6ffbash
./gradlew allTests
Ta5d6ff```

Tff7b72- Business logic tests
Tff7b72- Data model validation
Tff7b72- Search/ranking algorithm tests
Tff7b72- Route serialization tests

Tc9d1d9### Android Host Tests

Android-specific tests that run on JVM:

Ta5d6ff```Ta5d6ffbash
./gradlew Tffa657test
Ta5d6ff```

Tff7b72- ViewModel tests
Tff7b72- Repository tests with Room fakes
Tff7b72- Android-specific integration tests

Tc9d1d9### Compose UI Tests

Compose Multiplatform UI test framework:

Ta5d6ff```Ta5d6ffkotlin
Tf0883e@Test
Tff7b72fun Td2a8ffmyScreenTestTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runComposeUiTest Tb4b4b4{
Te6edf3setContent Tb4b4b4{ Te6edf3MyScreenTb4b4b4(Tb4b4b4) Tb4b4b4}
Te6edf3onNodeWithTextTb4b4b4(Ta5d6ff"Ta5d6ffExpectedTa5d6ff"Tb4b4b4)Tb4b4b4.Te6edf3assertIsDisplayedTb4b4b4(Tb4b4b4)
Tb4b4b4}
Ta5d6ff```

Located in Ta5d6ff`commonTest` or Ta5d6ff`jvmTest` source sets.

Tc9d1d9### Screenshot Tests

Uses Android Gradle Plugin's native (layoutlib) screenshot testing framework, split across two modules:

Tff7b72- **`:screenshot-tests`** β€” the **visual-regression gate**. CI runs Ta5d6ff`validateDebugScreenshotTest` on it; reframing one of these baselines is a real diff to review. Holds atomic, dual-purpose components.
Tff7b72- **`:docs-screenshots`** β€” **generate-only**, *not* validated in CI. Holds doc-framed compositions whose framing is tuned for the docs site, so reframing a doc image never churns the regression gate.

Ta5d6ff```Ta5d6ffbash
./gradlew :screenshot-tests:updateDebugScreenshotTest T8b949e# record regression goldens
./gradlew :screenshot-tests:validateDebugScreenshotTest T8b949e# compare against goldens (CI gate)
./gradlew :docs-screenshots:updateDebugScreenshotTest T8b949e# record doc-framed composition images
./gradlew :screenshot-tests:copyDocsScreenshots T8b949e# copy doc images from BOTH modules into docs/assets
Ta5d6ff```

Rendering is host-deterministic here (layoutlib): a local Ta5d6ff`update` produces references byte-identical to CI, so locally-recorded goldens pass Ta5d6ff`validate`. See Ta5d6ff`docs/assets/screenshots/README.md` for which module a new screenshot belongs in.

Tc9d1d9### Baseline Profile / Startup Performance

The Ta5d6ff`:baselineprofile` module (#5735) generates a [Tff7b72Baseline Profile](Te6edf3https://developer.android.com/topic/performance/baselineprofiles/overview) for Ta5d6ff`:androidApp`, AOT-compiling the hot startup paths so ART doesn't pay the JIT cost on first launch. It targets the **google** flavor (the variant most users run).

The Macrobenchmark generator (Ta5d6ff`BaselineProfileGenerator`) and the before/after benchmark (Ta5d6ff`StartupBenchmark`) live in Ta5d6ff`baselineprofile/src/main/kotlin/org/meshtastic/baselineprofile/`. Both run on a device/emulator:

Ta5d6ff```Ta5d6ffbash
./gradlew :androidApp:generateGoogleReleaseBaselineProfile T8b949e# Generate the profile (commit the output)
./gradlew :androidApp:benchmarkGoogleReleaseBaselineProfile T8b949e# Quantify the cold-start win
Ta5d6ff```

The generated profile is merged into Ta5d6ff`androidApp/src/google/generated/baselineProfiles/` and packaged into release builds via Ta5d6ff`androidx.profileinstaller`.

Tff7b72> ⚠️ **Warning:** The journey currently covers cold start only (launch β†’ first frame), because CI has no paired radio. Post-connection screens (node list, map, message thread) are not yet AOT-compiled; extend the journey once a fake transport or connected device is wired into the harness.

Tc9d1d9## Test Organization

Ta5d6ff```
feature/my-feature/src/
β”œβ”€β”€ commonTest/kotlin/org/meshtastic/feature/myfeature/
β”‚ β”œβ”€β”€ MyBusinessLogicTest.kt
β”‚ └── MyModelTest.kt
└── jvmTest/kotlin/org/meshtastic/feature/myfeature/
└── MyDesktopSpecificTest.kt
```

Tc9d1d9## Testing Guidelines

Tc9d1d9### DO

Tff7b72- Write tests in Ta5d6ff`commonTest` when possible (runs everywhere)
Tff7b72- Test business logic independently from UI
Tff7b72- Use fakes/stubs instead of mocks where practical
Tff7b72- Test edge cases: empty states, error states, boundary values
Tff7b72- Test deep link routing in Ta5d6ff`DeepLinkRouterTest`
Tff7b72- Keep tests fast β€” no network, no disk I/O in unit tests

Tc9d1d9### DON'T

Tff7b72- Don't test framework behavior (Compose internals, Room queries)
Tff7b72- Don't create tests that depend on other feature modules
Tff7b72- Don't use Ta5d6ff`Thread.sleep` β€” use coroutine test dispatchers
Tff7b72- Don't rely on test execution order

Tc9d1d9## Running Tests

Ta5d6ff```Ta5d6ffbash
T8b949e# All KMP tests
./gradlew allTests

T8b949e# Specific module
./gradlew :feature:docs:allTests

T8b949e# Code quality
./gradlew spotlessCheck detekt

T8b949e# Full verification
./gradlew spotlessCheck detekt kmpSmokeCompile Tffa657test allTests
Ta5d6ff```

Tc9d1d9## CI Integration

Tests run automatically on:
Tff7b72- Pull request creation/update
Tff7b72- Push to Ta5d6ff`main`
Tff7b72- Pre-release validation

CI runs on GitHub-hosted Ubuntu 24.04 runners (most jobs use the Ta5d6ff`ubuntu-24.04-arm` ARM runners, a few use Ta5d6ff`ubuntu-24.04`) with JDK 25 and Gradle caching.

---

Served by rngit 1.5.0 - Generated in 0.07s